Julia - Osnovna sintaksa - Izuzeci

In [1]:
#Programski jezik Julia takođe, kao i mnogi drugi programski jezici, ima ugrađene mehanizme za rad sa greškama 
#ukoliko do istih dođe prilikom izvršavanja naših programa. Ti mehanizmi nazivaju se izuzeci.
In [2]:
#Ovde ćemo dati jedan jednostavan primer kako možemo intuitivno, pomoću izuzetaka, izvršiti kontrolu toka nekog
#programa u slučaju dešavanja nepredviđene situacije:

a = 2; b = 1 + im;

#Ovde je prikazana najjednostavnija forma koju izutetak može da uzima: try-catch blok. U try bloku ispituje se
#da li je u izvršavanju programa došlo do greške - ako nije, program se izvršava do kraja try dela bloka i nastavlja
#dalje. Ali ako jeste, onda skačemo u catch granu i vršimo obradu izutetka

try
    println(sqrt(a*b))
catch
    println("Koren negativnog broja nije definisan")
end

println(a*b)
1.5537739740300374 + 0.6435942529055826im
2 + 2im
In [3]:
#Ono šta smo videli jeste da se ovaj program ipak korektno izvršio, budući da funkcija sqrt() radi i sa kompleksnim
#brojevima, a a*b će zaista rezultovati jednim kompleksnim brojem.
In [4]:
#Ono šta ćemo sad uraditi biće situacija kada dolazi do neregularnosti prilikom izvršavanja našeg try bloka:

a = -2; b = 1 + 2*im;

try
    println(sqrt(a))
catch
    println("Koren negativnog broja nije definisan")
end

println(a*b)
Koren negativnog broja nije definisan
-2 - 4im
In [5]:
#Kao što smo mogli da vidimo, zbog negativnosti realnog broja a došlo je do neregularne situacije, pa smo morali da
#preusmerimo tok izvršavanja našeg programa u catch granu. Ono gde se Julia razlikuje od ostalih programskih jezika 
#jeste to da će se kod nakon izvršavanja catch bloka ipak izvršiti - odnosno implicitno se podrazumeva da 
#je u našem catch bloku izvršena korekcija programa i da on može dalje nesmetano da teče, što u drugim programskim
#jezicima nije slučaj.
In [6]:
#Sada ćemo uvesti mehanizam bacanja izuzetaka u našem programu:

#Posmatrajmo sledeću situaciju: Definisaćemo funkciju koja za prosleđene argumente a i b daje vrednost izraza
# a + sqrt(b), samo ako je a > b. Jasno, ukoliko je b manje od 0, doći će do greške prilikom izvvršavanja programa.
#Zato ćemo ovde baš imati situaciju bacanja izutetka u datom slučaju

function val_exp(a,b)
    if(b < 0 || b < a) 
        throw(error())
    end
    return a + sqrt(b)
end
Out[6]:
val_exp (generic function with 1 method)
In [7]:
try
    println("Vrednosti izraza za a=9, b=1 je: " , val_exp(9, 1))
catch e
    println("Došlo je do greške")
end
Došlo je do greške
In [8]:
#Ono šta se može primetiti jeste da je izuzetak bacila funkcija val_exp, a uhvatio ga je kod iz try-catch bloka:
#Ovde možemo videti da postoji hijerarhija prilikom razrešavanja hvatanja izutekaka. Naime, neka je data sledeća šema
#poziva u toku izvršavanja funkcija:

# blok1 poziva blok 2, blok 2 poziva blok 3 itd. ... blok N-1 poziva blok N
#Ukoliko je izuzetak bačen u okviru bloka k, prvo će se pokušati njegovo razrešavanje u tom bloku. Ukoliko 
#ne postoji nijedan catch blok u okviru bloka k, onda će se pokušati sa razrešavanjem u bloku k - 1 itd. sve do 
#bloka 1. On će ujedno pokretati redom i sve catch blokove dok ne dođe do try bloka koji se uspešno
#do kraja izvršio, čak i ako se on sastoji od pokrenutih catch blokova.
#Ovo je opšti princip za rad sa izuzecima u programskom jeziku Julia.
In [9]:
#Ovu situaciju možemo demonstrirati na sledećem primeru:

try
    try
        println(val_exp(0, 17))
        try
            println(val_exp(9, 17))
            println(val_exp(1, -5))
        catch e1
            println("Nekorektan unos podataka - treći nivo")
            throw(error())
        end
    catch e2
    println("Nekorektan unos podataka - drugi nivo")
    end
catch e3
println("Nekorektan unos podataka - prvi nivo")
end
4.123105625617661
13.123105625617661
Nekorektan unos podataka - treći nivo
Nekorektan unos podataka - drugi nivo
In [10]:
#U slučaju kada imamo situaciju da postoji nešto šta mora da se izvrši, bez obzira na to da li je izuzetak bačen ili
#nije, možemo za to da koristimo ključnu reč finally koja će za cilj imati da se odgovarajuća radnja koja je obavezna
#njom zaokruži, i onda će se ona sigurno izvršiti. Ona ide u paru sa try i catch blokovima na potpuno isti način kao
# i oni. Na primer:

a = 0;

try
    b = 2;
    println(b);
    a = 5;
    println(a);   
    throw(error());
catch
finally
    if a > 0
        b = 4;
    end
    println(b);
end
2
5
4
In [11]:
#Programski jezik Julia napravljen je tako da za svaki try mora postojati odgovarajući catch ili finally izraz
#Zaista, pokretanjem sledećeg koda, Julia će nam prijaviti sledeću grešku:

try
    try
        println(val_exp(0, 17))
        try
            println(val_exp(9, 17))
            println(val_exp(1, -5))
        end
    end
end
syntax: try without catch or finally
In [ ]:

In [ ]: